package com.ruijie.acl.web;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.collections.CollectionUtils;
import org.jboss.seam.annotations.In;
import org.springframework.util.Assert;

import com.ruijie.acl.AclPlanParameters;
import com.ruijie.acl.service.AclPlanParametersService;
import com.ruijie.acl.utils.AclUtil;
import com.ruijie.acl.web.config.Constants;
import com.ruijie.batch.execution.PlanExecutionService;
import com.ruijie.batch.plan.BatchPlan;
import com.ruijie.batch.plan.PlanDefinitionRequest;
import com.ruijie.batch.plan.PlanDefinitionService;
import com.ruijie.batch.plan.items.ExtendPlanDefinitionRequest;
import com.ruijie.batch.plan.items.ExtendPlanDefinitionService;
import com.ruijie.batch.plan.items.ItemParameters;
import com.ruijie.batch.task.Task;
import com.ruijie.batch.task.TaskRegistry;
import com.ruijie.emp.components.deviceselector.TempDevice;
import com.ruijie.emp.components.deviceselector.service.DeviceSelectorService;

/**
 * <p>
 * Title:ACL项目的有使用计划的Action基础类
 * </p>
 * <p>
 * Description: ACL项目的有使用计划的Action基础类
 * </p>
 * <p>
 * Copyright: Copyright (c) 2009
 * </p>
 * <p>
 * Company: Ruijie Co., Ltd.
 * </p>
 * <p>
 * Create Time: 2009-9-15
 * </p>
 * <p>
 * Update Time:
 * </p>
 * <p>
 * Updater:
 * </p>
 * <p>
 * Update Comments:
 * </p>
 * 
 * @author ASAI
 */
public abstract class AclPlanBaseAction extends AclBaseAction {

	private String uuid;

	private String taskCode;
	
    @In("#{extendPlanDefinitionService}")
    private ExtendPlanDefinitionService extendPlanDefinitionService;
    
	@In("#{aclDeviceSelectorService}")
	private DeviceSelectorService aclDeviceSelectorService;

	@In("#{taskRegistry}")
	private TaskRegistry taskRegistry;

    @In("#{planExecutionService}")
    private PlanExecutionService planExecutionService;
    
    @In("#{aclPlanParametersService}")
    private AclPlanParametersService aclPlanParametersService;

	/**
	 * 初始化要保存的计划
	 * 
	 * @param req
	 */
	protected void initRequest(PlanDefinitionRequest req) {
		req.setSessionCode(this.getUuid());
		req.setTempTable("ET_DEV_TEMP_SELECTOR");
		req.setTempTableFilterColumn("UUID");
		req.setTempTableItemColumn("DEVICE_ID");
		// ADHOC
		req.setPlanType(PlanDefinitionRequest.PLAN_TYPE__ADHOC);
		// 忽略失败
		req.applyIgnoreException();
		// 执行任务
		req.setTask(getTask());
		// 计划名称
		req.setPlanName("AutoDeploy-" + AclUtil.createUniqueID());
		// 立即下发
		req.removeStepSchedule(Constants.ACL_DEPLOY_PLAN_ITEM_PARAM_NAME);
	}

	protected void prepareItemParameters(ExtendPlanDefinitionRequest req) {
		Assert.notNull(req);
		req.setSessionCode(this.getUuid());
		// here we will populate the ExtendPlanDefinitionRequest's
		// itemParameters.
		((ExtendPlanDefinitionService) getPlanDefinitionService())
				.populateExtendDefinitionRequest(req);
		// prepareItemList(req.getItemParameters());
	}

	/**
	 * 保存ACL部署计划的参数
	 */
	@SuppressWarnings("unchecked")
	public void saveAclPlanParameters(List<AclPlanParameters> paramList) {
		if (paramList != null && paramList.size() > 0) {
			Long[] arrId = new Long[paramList.size()];
			Map<Long, Long> paramMap = new HashMap<Long, Long>();

			for (int i = 0; i < paramList.size(); i++) {
				AclPlanParameters planParam = paramList.get(i);
				this.getAclPlanParametersService().save(planParam);
				arrId[i] = planParam.getDevice().getId();
				paramMap.put(planParam.getDevice().getId(), planParam.getId());
			}

			// 
			ExtendPlanDefinitionRequest req = instantizePlanDefinitionRequest();
			this.initRequest(req);
			// 选中要下发的设备
			this.getAclDeviceSelectorService().select(this.getUuid(), arrId);
			this.prepareItemParameters(req);
			ExtendPlanDefinitionRequest request = (ExtendPlanDefinitionRequest) req;
			Collection itemParameters = request.getItemParameters();
			if (!CollectionUtils.isEmpty(itemParameters)) {
				for (Object entry : itemParameters) {
					TempDevice item = (TempDevice) ((Object[]) entry)[0];
					ItemParameters parameters = (ItemParameters) ((Object[]) entry)[1];
					if (parameters == null) {
						parameters = new ItemParameters();
						((Object[]) entry)[1] = parameters;
					}
					parameters.setItem(item.getReal().getId());
					parameters.putParameter(
							Constants.ACL_DEPLOY_PLAN_ITEM_PARAM_NAME, paramMap
									.get(item.getReal().getId()).toString());
				}
			}

			BatchPlan batchPlan = this.getPlanDefinitionService().saveOrUpdateBatchPlan(req);
			this.uuid = null;
			// 启动计划
			planExecutionService.submitBatchPlanExecution(batchPlan);
			
		}
	}

	protected ExtendPlanDefinitionRequest instantizePlanDefinitionRequest() {
		return new ExtendPlanDefinitionRequest();
	}

	/**
	 * 取得任务
	 * 
	 * @return 任务
	 */
	public Task getTask() {
		return taskRegistry.getTask(taskCode);
	}

	public String getTaskCode() {
		if (AclUtil.empty(this.taskCode)){
			this.taskCode = Constants.ACL_DEPLOY_ACTION_TASK_CODE_MULTIPLE;
		}
		return taskCode;
	}

	public void setTaskCode(String taskCode) {
		this.taskCode = taskCode;
	}

	public String getUuid() {
		if (AclUtil.empty(this.uuid)) {
			this.uuid = UUID.randomUUID().toString();
		}
		return uuid;
	}

	public PlanDefinitionService getPlanDefinitionService() {
		return extendPlanDefinitionService;
	}

	public AclPlanParametersService getAclPlanParametersService() {
		return aclPlanParametersService;
	}

	public DeviceSelectorService getAclDeviceSelectorService() {
		return aclDeviceSelectorService;
	}
}
